import app from '../../../app'
import { level } from 'winston'
import {
  filterTreeData
} from '../../helpers/utilsJS'
//#region AutoCreateCode
import {
  hideObjectKeysWithoutValues,
  hideSelectedObjectKeys,
  processIdValue,
  processIdArray,
} from '../../helpers/utilsJS';
import { deleteFromCache, setExCache } from '../../helpers/redis';
import log from "../../helpers/logger";
import { RequestParserService } from '../../lib/request-parser/src';
import { generateRowLevelPermissionFilter, checkUserHasPermission, getUserAuthorizedDataIds } from '../../helpers/permissionUtils';
import { PERMISSION_LEVEL } from '../../middlewares/auth/rowLevelPermission';
import { PrismaClient } from '../../../../prisma/generated/uctoo'

const db = new PrismaClient({
  log: ['query', 'info', 'warn', 'error'],
});

// 定义当前表的ID字段类型
const ID_FIELD_TYPE = 'uuid';

export async function createPermissions(permissions) {
  try {
    permissions = hideSelectedObjectKeys(permissions, ['id']);
    const newPermissions = await db.permissions.create({
      data: {
        ...permissions
      },
    });
    //Cache after create
    // setExCache(newPermissions.id, 3600, JSON.stringify(newPermissions));
    return newPermissions;
  } catch (e) {
    log.error(e);
    return false;
  }
}

export async function editPermissionsInDatabase(updatedPermissions, permissionsId, userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 如果启用了行级权限且提供了userId，检查是否有写权限
    if (isEnabled && userId) {
      const permissionResult = await checkUserHasPermission(userId, 'permissions', permissionsId, PERMISSION_LEVEL.WRITE);
      if (!permissionResult.hasPermission) {
        log.warn(`User ${userId} has no permission to edit permissions ${permissionsId}: ${permissionResult.reason}`);
        return { success: false, reason: permissionResult.reason };
      }
    }
    
    updatedPermissions = hideSelectedObjectKeys(updatedPermissions, ['id']);
    updatedPermissions = hideObjectKeysWithoutValues(updatedPermissions);
    updatedPermissions.updated_at = new Date().toISOString(); 
    if(updatedPermissions.deleted_at === "0"){  //recycle data
      const permissionsFromDb = await db.permissions.update({
        data: { deleted_at: { set: null } },
        where: {
          id: processIdValue(permissionsId, ID_FIELD_TYPE),
        },
      });
      //Cache after edit
      // setExCache(permissionsFromDb.id, 3600, JSON.stringify(permissionsFromDb));
      if (!permissionsFromDb) return { success: false, reason: '实体不存在' };
      return { success: true, data: permissionsFromDb };
    }else{
      
      const permissionsFromDb = await db.permissions.update({
        data: updatedPermissions,
        where: {
          id: processIdValue(permissionsId, ID_FIELD_TYPE),
        },
      });
      //Cache after edit
      // setExCache(permissionsFromDb.id, 3600, JSON.stringify(permissionsFromDb));
      if (!permissionsFromDb) return { success: false, reason: '实体不存在' };
      return { success: true, data: permissionsFromDb };
    }
    
  } catch (e) {
    log.error(e);
    return { success: false, reason: '编辑实体时发生错误' };
  }
}

export async function editMultiPermissionsInDatabase(updatedPermissions, ids, userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 如果启用了行级权限且提供了userId，检查是否对每个实体都有写权限
    if (isEnabled && userId) {
      for (const permissionsId of ids) {
        const permissionResult = await checkUserHasPermission(userId, 'permissions', permissionsId, PERMISSION_LEVEL.WRITE);
        if (!permissionResult.hasPermission) {
          log.warn(`User ${userId} has no permission to edit permissions ${permissionsId}: ${permissionResult.reason}`);
          return { success: false, reason: permissionResult.reason, permissionsId: permissionsId };
        }
      }
    }
    
    updatedPermissions = hideSelectedObjectKeys(updatedPermissions, ['id','ids']);
    updatedPermissions = hideObjectKeysWithoutValues(updatedPermissions);
    updatedPermissions.updated_at = new Date().toISOString(); 
    if(updatedPermissions.deleted_at === "0"){  //recycle data
      const permissionsFromDb = await db.permissions.updateMany({
        data: { deleted_at: { set: null } },
        where: {
          id: {in: processIdArray(ids, ID_FIELD_TYPE)},
        },
      });
      if (!permissionsFromDb) return { success: false, reason: '未找到要恢复的实体' };
      return { success: true, data: permissionsFromDb };
    }else{
      const permissionsFromDb = await db.permissions.updateMany({
        data: updatedPermissions,
        where: {
          id: {in: processIdArray(ids, ID_FIELD_TYPE)},
        },
      });
      if (!permissionsFromDb) return { success: false, reason: '未找到要编辑的实体' };
      return { success: true, data: permissionsFromDb };
    }
    
  } catch (e) {
    log.error(e);
    return { success: false, reason: '批量编辑实体时发生错误' };
  }
}

export async function deletePermissionsFromDatabase(permissionsId,force = 0, userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 如果启用了行级权限且提供了userId，检查是否有写权限
    if (isEnabled && userId) {
      const permissionResult = await checkUserHasPermission(userId, 'permissions', permissionsId, PERMISSION_LEVEL.WRITE);
      if (!permissionResult.hasPermission) {
        log.warn(`User ${userId} has no permission to delete permissions ${permissionsId}: ${permissionResult.reason}`);
        return { success: false, reason: permissionResult.reason };
      }
    }
    
    if(force){  //real delete data
      await db.permissions.delete({
        where: {
          id: processIdValue(permissionsId, ID_FIELD_TYPE),
        },
      });
    }else{  //soft delete
      await db.permissions.update({
        data: {deleted_at: new Date().toISOString()},
        where: {
          id: processIdValue(permissionsId, ID_FIELD_TYPE),
        },
      });
    }
    // deleteFromCache(permissionsId);
    return { success: true };
  } catch (e) {
    log.error(e);
    return { success: false, reason: '删除实体时发生错误' };
  }
}

export async function deleteMultiPermissionsFromDatabase(ids,force = 0, userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 如果启用了行级权限且提供了userId，检查是否对每个实体都有写权限
    if (isEnabled && userId) {
      for (const permissionsId of ids) {
        const permissionResult = await checkUserHasPermission(userId, 'permissions', permissionsId, PERMISSION_LEVEL.WRITE);
        if (!permissionResult.hasPermission) {
          log.warn(`User ${userId} has no permission to delete permissions ${permissionsId}: ${permissionResult.reason}`);
          return { success: false, reason: permissionResult.reason, permissionsId: permissionsId };
        }
      }
    }
    
    if(force){  //real delete multi data
      await db.permissions.deleteMany({
        where: {
          id:{in: processIdArray(ids, ID_FIELD_TYPE)},
        },
      });
    }else{  //soft delete
      await db.permissions.updateMany({
        data: {deleted_at: new Date().toISOString()},
        where: {
          id: {in: processIdArray(ids, ID_FIELD_TYPE)},
        },
      });
    }
    // deleteFromCache(permissionsId);
    return { success: true };
  } catch (e) {
    log.error(e);
    return { success: false, reason: '批量删除实体时发生错误' };
  }
}

export async function getPermissionsFromDatabase(permissionsId, userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 首先检查实体是否存在
    const permissionsFromDb = await db.permissions.findFirst({
      where: {
          id: processIdValue(permissionsId, ID_FIELD_TYPE),
        },
    });
    
    // 如果实体不存在，直接返回null
    if (!permissionsFromDb) return null;
    
    // 如果启用了行级权限且提供了userId，检查权限
    if (isEnabled && userId) {
      const hasPermission = await checkUserHasPermission(userId, 'permissions', permissionsId, PERMISSION_LEVEL.READ);
      if (!hasPermission) {
        // 用户没有权限访问此实体
        return null;
      }
    }
    
    return permissionsFromDb;
  } catch (e) {
    log.error(e);
    return false;
  }
}

export async function getPermissionssFromDatabase(limit, page, skip, userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 使用更明确的类型定义，允许OR属性
    const whereCondition: any = {};
    
    // 如果启用了行级权限且提供了userId，添加权限过滤
    if (isEnabled && userId) {
      // 获取用户有权访问的实体ID列表
      const authorizedIds = await getUserAuthorizedDataIds(userId, 'permissions', PERMISSION_LEVEL.READ);
      
      // 组合条件：用户创建的实体 或 用户被授权访问的实体
      whereCondition.OR = [
        { creator: userId },
        { id: { in: authorizedIds } }
      ];
    }
    
    const permissionssFromDb = await db.permissions.findMany({
      skip: limit * page + skip,
      take: limit,
      where: whereCondition
    });
    if (!permissionssFromDb) return null;
    return permissionssFromDb;
  } catch (e) {
    log.error(e);
    return false;
  }
}

export async function queryPermissionssFromDatabase(limit, page, skip, query, userId?) {
  try {
    const requestParserService = new RequestParserService();
    const parsedQuery = requestParserService.parseQuery(query);
    // 使用any类型允许动态添加OR和AND属性
    const filter: any = parsedQuery.filter || {};
    
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    // 如果启用了行级权限且提供了userId，添加权限过滤
    if (isEnabled && userId) {
      // 获取用户有权访问的实体ID列表
      const authorizedIds = await getUserAuthorizedDataIds(userId, 'permissions', PERMISSION_LEVEL.READ);
      
      // 组合条件：原始查询条件 + (用户创建的实体 或 用户被授权访问的实体)
      const originalWhere = { ...filter };
      
      // 组合条件：用户创建的实体 或 用户被授权访问的实体
      filter.OR = [
        { creator: userId },
        { id: { in: authorizedIds } }
      ];
      
      // 如果原始查询条件不为空，将其合并到每个OR条件中
      if (Object.keys(originalWhere).length > 0) {
        filter.AND = [originalWhere];
      }
    }
    
    const permissionssFromDb = await db.permissions.findMany({
      skip: limit * page + skip,
      take: limit,
      where: filter,
      orderBy: parsedQuery.sort,
    });
    if (!permissionssFromDb) return null;
    return permissionssFromDb;
  } catch (e) {
    log.error(e);
    return false;
  }
}

export async function countPermissionss(userId?) {
  try {
    const isEnabled = process.env.ROW_LEVEL_PERMISSION_ENABLED === 'true';
    
    let totalCount = 0;
    
    // 如果启用了行级权限且提供了userId，使用不同的方式处理权限过滤
    if (isEnabled && userId) {
      // 获取用户有权访问的实体ID列表
      const authorizedIds = await getUserAuthorizedDataIds(userId, 'permissions', PERMISSION_LEVEL.READ);
      
      // 直接在初始化时定义OR属性，避免类型错误
      const whereCondition = {
        OR: [
          { creator: userId },
          { id: { in: authorizedIds } }
        ]
      };
      
      // 计算符合条件的实体数量
      totalCount = await db.permissions.count({
        where: whereCondition
      });
    } else {
      // 不启用行级权限时，直接计算所有实体数量
      totalCount = await db.permissions.count();
    }
    
    return totalCount;
  } catch (e) {
    log.error(e);
    return false;
  }
}
//#endregion AutoCreateCode

//查询树状菜单，todo: 目前仅支持三层，后续支持递归无限层级
export async function getPermissionsTree() {
  try {
    const permissionssFromDb = await db.permissions.findMany({
      where: { parent_id: null, hidden: 1 },
      include: {
        children: {
          include: {
            children: {
              orderBy: {
                weight: 'asc',
              },
            },
          },
          orderBy: {
            weight: 'asc',
          },
        },
      },
      orderBy: {
        weight: 'asc',
      },
    })
    return permissionssFromDb
  } catch (e) {
    log.error(e)
    return false
  }
}

//查询树状菜单，todo: 目前仅支持三层，后续支持递归无限层级
export async function getUserPermissionsTree(user) {
  try {
    const uctooUserGroup = await db.user_has_group.findMany({
      where: {
        groupable_id: user,
      },
      select:{
        group_id:true
      }
    });
// 提取所有userGroupId
const userGroupIds = uctooUserGroup.map(uug => uug.group_id)
  // 根据userGroupId获取所有permissionId
  const userGroupPermissions = await db.group_has_permission.findMany({
    where: {
      group_id: {
        in: userGroupIds,
      },
    },
    select: {
      permission_name: true,
    },
  })
  // 提取所有permissionName
  const permissionNames = userGroupPermissions.map(ugp => ugp.permission_name)
    

    const userPermissionssFromDb = await db.permissions.findMany({
      where: { name: {
        in:permissionNames
      } },
      orderBy: {
        weight: 'asc',
      },
    })
    //提取所有id
    const userPermissionIds = userPermissionssFromDb.map(userP => userP.id);
    //将父节点也加入结果
    const parentPermissionIds = userPermissionssFromDb.map(userP => userP.parent_id );
    //合并
    const mergedIds = [...userPermissionIds, ...parentPermissionIds].filter((item): item is string => item != null);
    //查询一次包含父节点权限集
    const mergedPermissionssFromDb = await db.permissions.findMany({
      where: { id: {
        in:mergedIds
      } },
      orderBy: {
        weight: 'asc',
      },
    })
    //提取所有id
    const mergedPermissionIds = mergedPermissionssFromDb.map(userP => userP.id);
    //将父节点也加入结果
    const mergedParentPermissionIds = mergedPermissionssFromDb.map(userP => userP.parent_id);
    //合并
    const allIds = [...mergedPermissionIds, ...mergedParentPermissionIds].filter((item): item is string => item != null); 

    //全部权限树
    const permissionssFromDb = await db.permissions.findMany({
      where: { parent_id: null, hidden: 1, id: {in: allIds},type:1 },
      include: {
        children: {
          where: { id: {in: allIds} },
          include: {
            children: {
              where: { id: {in: allIds} },
              orderBy: {
                weight: 'asc',
              },
            },
          },
          orderBy: {
            weight: 'asc',
          },
        },
      },
      orderBy: {
        weight: 'asc',
      },
    })
    return permissionssFromDb
  } catch (e) {
    log.error(e)
    return false
  }

  
}

//从数据库刷新所有表菜单
export async function refreshDbMenus() {
  try {
    let tablesFromDb = await db.db_info.findMany({
      distinct: ['table_name'],
      select: {
        table_name: true,
      },
      orderBy: {
        table_name: 'asc',
      },
    })
    //查询数据库父菜单
    let dbParentMenu = await db.permissions.findFirst({
      where: {
        name: 'Database',
      },
    })
    //没有数据库父级菜单创建一个
    if (!dbParentMenu) {
      const dbMenuData = {
        component: 'BasicLayout',
        redirect: '/database',
        path: '/database',
        name: 'Database',
        level: '0',
        meta: {
          icon: 'mdi:database-sync',
          order: 9999,
          title: 'page.dashboard.database',
          keepAlive: true,
        },
      }
      dbParentMenu = await db.permissions.create({
        data: dbMenuData,
      })
    }

    //清空数据库菜单下已有数据
    const deleteMenus = await db.permissions.deleteMany({
      where: {
        parent_id: dbParentMenu.id,
      },
    })

    //加入所有数据库菜单
    let tablesMenu = [];
    for (let i = 0; i < tablesFromDb.length; i++) {
      let innerArray = tablesFromDb[i]
      tablesFromDb[i]['name'] = 'database.'+innerArray.table_name
      tablesFromDb[i]['parent_id'] = dbParentMenu.id
      tablesFromDb[i]['component'] = '/' + innerArray.table_name + '/index'
      tablesFromDb[i]['path'] = '/database/' + innerArray.table_name
      tablesFromDb[i]['weight'] = i
      tablesFromDb[i]['meta'] = {
        icon: 'mdi:database-sync',
        title: 'database.' + innerArray.table_name,
      }
      delete tablesFromDb[i].table_name
    }

    tablesMenu = tablesFromDb;

    const createMenus = await db.permissions.createMany({
      data: tablesMenu,
      skipDuplicates: true,
    })

    return createMenus
  } catch (e) {
    log.error(e)
    return false
  }
}

//从服务端应用刷新所有路由记录到数据库权限节点表
export async function refreshRoutes() {
  try {
    //查询API父菜单
    let APIParentMenu = await db.permissions.findFirst({
      where: {
        name: 'API',
      },
    })
    //没有API父级菜单创建一个
    if (!APIParentMenu) {
      const APIMenuData = {
        component: 'BasicLayout',
        redirect: '/API',
        path: '/API',
        name: 'API',
        level: '0',
        meta: {
          icon: 'mdi:database-sync',
          order: 9999,
          title: 'page.dashboard.API',
          keepAlive: true,
        },
      }
      APIParentMenu = await db.permissions.create({
        data: APIMenuData,
      })
    }

    const allRoutes = JSON.stringify(app.routes);  //服务端应用全部路由
    
    let appRoutes = [];
    appRoutes[0] = {name:'/*',method:'ANY',path:'/*',type:3, parent_id: APIParentMenu.id};  //API权限节点类型为3
    let i = 1;
    for (const [key, value] of Object.entries(app.routes)) {
      for (const [innerkey, innervalue] of Object.entries(value)) {
        if(innerkey !== '/*'){
          appRoutes[i] = {name:innervalue.pattern, method:innervalue.method, path:innervalue.pattern, type:3, parent_id:APIParentMenu.id};
          i++;
        }
        
      }
    }
    //加入数据库权限节点表
    const createMenus = await db.permissions.createMany({
      data: appRoutes,
      skipDuplicates: true,
    })
    return JSON.stringify(appRoutes)
  } catch (e) {
    log.error(e)
    return false
  }
}


//查询树状菜单，todo: 目前仅支持三层，后续支持递归无限层级
export async function getGroupPermissionsTree(group_id) {
  try {
  // 根据userGroupId获取所有permissionId
  const userGroupPermissions = await db.group_has_permission.findMany({
    where: {
      group_id: group_id,
    },
    select: {
      permission_name: true,
    },
  })
  // 提取所有permissionName
  const permissionNames = userGroupPermissions.map(ugp => ugp.permission_name)
    

    const userPermissionssFromDb = await db.permissions.findMany({
      where: { name: {
        in:permissionNames
      } },
      orderBy: {
        weight: 'asc',
      },
    })
    //提取所有id
    const userPermissionIds = userPermissionssFromDb.map(userP => userP.id);
    //全部权限树
    const permissionssFromDb = await db.permissions.findMany({
      where: { parent_id: null, hidden: 1, id: {in: userPermissionIds},type:1 },
      include: {
        children: {
          where: { id: {in: userPermissionIds} },
          include: {
            children: {
              where: { id: {in: userPermissionIds} },
              orderBy: {
                weight: 'asc',
              },
            },
          },
          orderBy: {
            weight: 'asc',
          },
        },
      },
      orderBy: {
        weight: 'asc',
      },
    })
    return permissionssFromDb
  } catch (e) {
    log.error(e)
    return false
  }
}

//查询用户组所有权限ID
export async function getCheckedGroupPermissionsId(group_id) {
  try {
  // 根据userGroupId获取所有permissionId
  const userGroupPermissions = await db.group_has_permission.findMany({
    where: {
      group_id: group_id,
    },
    select: {
      permission_name: true,
    },
  })
  // 提取所有permissionName
  const permissionNames = userGroupPermissions.map(ugp => ugp.permission_name)
    

    const userPermissionssFromDb = await db.permissions.findMany({
      where: { name: {
        in:permissionNames
      } },
      orderBy: {
        weight: 'asc',
      },
    })
    //提取所有id
    const userPermissionIds = userPermissionssFromDb.map(userP => userP.id);
    return userPermissionIds
  } catch (e) {
    log.error(e)
    return false
  }
}